package com.qf.aop.config;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Optional;

/**
 * @Author: sin
 * @Date: 2025/5/21 22:10
 * @Description:
 **/
@Slf4j
public class Ip2regionUtil {

    private static final String UNKNOWN = "unknown";
    private static final String LOOPBACK_IPV6 = "0:0:0:0:0:0:0:1";
    private static final String LOCALHOST = "127.0.0.1";

    private static final String IP2REGION_FILE = "ip2region.xdb";
    private static byte[] ip2regionBuffer;
    private static Searcher searcher;

    static {
        try (InputStream is = Ip2regionUtil.class.getClassLoader().getResourceAsStream(IP2REGION_FILE)) {
            if (is == null) {
                throw new RuntimeException("未找到 ip2region.xdb 文件");
            }
            ip2regionBuffer = is.readAllBytes();
            if (ip2regionBuffer == null || ip2regionBuffer.length == 0) {
                throw new RuntimeException("ip2region.xdb 文件内容为空");
            }
            searcher = Searcher.newWithBuffer(ip2regionBuffer);
        } catch (IOException e) {
            // 可选：添加日志记录
            // logger.error("读取 ip2region.xdb 文件失败", e);
            throw new RuntimeException("读取 ip2region.xdb 文件失败");
        } catch (Exception e) {
            // logger.error("初始化 ip2region 搜索器失败", e);
            throw new RuntimeException("初始化 ip2region 搜索器失败");
        }
    }


    private Ip2regionUtil() {
    }

    /**
     * 获取客户端真实 IP 地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String[] headers = {
                "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP",
                "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP",
                "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA",
                "REMOTE_ADDR"
        };

        for (String header : headers) {
            String ip = request.getHeader(header);
            if (StringUtils.hasText(ip) && !UNKNOWN.equalsIgnoreCase(ip)) {
                return extractFirstIp(ip);
            }
        }

        String ip = request.getRemoteAddr();
        return LOOPBACK_IPV6.equals(ip) ? LOCALHOST : extractFirstIp(ip);
    }

    private static String extractFirstIp(String ip) {
        if (ip != null && ip.contains(",")) {
            return ip.split(",")[0].trim();
        }
        return ip;
    }

    /**
     * 获取物理地址（省市ISP）
     */
    public static String getAddr(String ip) {
        try {
            if (searcher == null) {
                return "未知";
            }

            String region = searcher.search(ip);
            String[] parts = region.split("\\|");
            System.out.println("======================");

            for (String part : parts) {
                System.out.println(part);
            }
            System.out.println("======================");
            if (parts.length < 5) return "未知";
            return parts[2] + parts[3] + " " + parts[4];
        } catch (Exception e) {
            log.error("查询 IP 地址 [{}] 失败：{}", ip, e.getMessage(), e);
            return "未知";
        }
    }

    /**
     * 获取浏览器类型
     */
    public static String getBrowser(HttpServletRequest request) {
        String ua = Optional.ofNullable(request.getHeader("User-Agent")).orElse("").toLowerCase();

        if (ua.contains("edge")) return "Edge";
        if (ua.contains("chrome")) return "Chrome";
        if (ua.contains("firefox")) return "Firefox";
        if (ua.contains("safari") && !ua.contains("chrome")) return "Safari";
        if (ua.contains("msie") || ua.contains("trident")) return "Internet Explorer";
        return "Unknown";
    }

    /**
     * 获取操作系统
     */
    public static String getOs(HttpServletRequest request) {
        String ua = Optional.ofNullable(request.getHeader("User-Agent")).orElse("").toLowerCase();

        if (ua.contains("windows nt 10")) return "Windows 10";
        if (ua.contains("windows nt 6.1")) return "Windows 7";
        if (ua.contains("mac os x")) return "Mac OS X";
        if (ua.contains("android")) return "Android";
        if (ua.contains("iphone")) return "iOS";
        return "Unknown";
    }
}
